package control;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;


public class CassandraMonitor {
	protected static final int DEFAULT_JMX_PORT = 7199;
	protected static final String DEFAULT_HOST = "localhost";

	protected final String host;
	protected final int port;
	protected final String username;
	protected final String password;
	private static final String FMT_URL = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi";
	private JMXConnector jmxc;
	private MBeanServerConnection mbeanServerConn;

	/**
	 * @param args
	 * @throws IOException 
	 * @throws ReflectionException 
	 * @throws MBeanException 
	 * @throws NullPointerException 
	 * @throws InvalidAttributeValueException 
	 * @throws InstanceNotFoundException 
	 * @throws AttributeNotFoundException 
	 * @throws MalformedObjectNameException 
	 */
	public static void main(String[] args) throws IOException, MalformedObjectNameException, AttributeNotFoundException, InstanceNotFoundException, InvalidAttributeValueException, NullPointerException, MBeanException, ReflectionException {
		// TODO Auto-generated method stub
		CassandraMonitor monitor=new CassandraMonitor("192.168.3.228", 7199, "","");
		monitor.setThreadSize(16);
		monitor.close();
	}
	
	CassandraMonitor(String host, int port, String username, String password) throws IOException
	{
		this.host = host;
		this.port = port;
		this.username = username;
		this.password = password;
		connect();
	}
	private void connect() throws IOException
	{
		JMXServiceURL jmxUrl = new JMXServiceURL(String.format(FMT_URL, host, port));
		Map<String, Object> env = new HashMap<String, Object>();

		if (username != null)
			env.put(JMXConnector.CREDENTIALS, new String[]{ username, password });

		jmxc = JMXConnectorFactory.connect(jmxUrl, env);
		mbeanServerConn = jmxc.getMBeanServerConnection();
	}
    public void close() throws IOException
    {
        jmxc.close();
    }
    public void setThreadSize(int rate) throws MalformedObjectNameException, NullPointerException, AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException, InvalidAttributeValueException{
		 	ObjectName name=new ObjectName("org.apache.cassandra.request:type=MutationStage");
		    int serverRate=(Integer)mbeanServerConn.getAttribute(name, "CorePoolSize");
		    Attribute attribute=new Attribute("CorePoolSize", rate);
		    mbeanServerConn.setAttribute(name, attribute);
		    name=new ObjectName("org.apache.cassandra.request:type=MutationStage");
		    serverRate=(Integer)mbeanServerConn.getAttribute(name, "CoreThreads");
		    attribute=new Attribute("CoreThreads", rate);
		    mbeanServerConn.setAttribute(name, attribute);
		    name=new ObjectName("org.apache.cassandra.request:type=MutationStage");
		    serverRate=(Integer)mbeanServerConn.getAttribute(name, "MaximumThreads");
		    attribute=new Attribute("MaximumThreads", rate);
		    mbeanServerConn.setAttribute(name, attribute);
	}
    
    static class CassandraTimerTask  extends TimerTask{
    	CassandraMonitor monitor;
    	int thread;
    	public CassandraTimerTask(CassandraMonitor monitor,int thread){
    		this.monitor=monitor;
    		this.thread=thread;
    	}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				monitor.setThreadSize(thread);
			} catch (MalformedObjectNameException e) {
				e.printStackTrace();
			} catch (AttributeNotFoundException e) {
				e.printStackTrace();
			} catch (InstanceNotFoundException e) {
				e.printStackTrace();
			} catch (InvalidAttributeValueException e) {
				e.printStackTrace();
			} catch (NullPointerException e) {
				e.printStackTrace();
			} catch (MBeanException e) {
				e.printStackTrace();
			} catch (ReflectionException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    	
    }
}

